package com.iot08.api.controller;

import com.iot08.api.annotation.CheckAppSign;
import com.iot08.api.service.supplement.PayService;
import com.iot08.api.utils.IPUtil;

import com.iot08.api.utils.request.ParamHandle;
import com.iot08.api.utils.wxpay.WxPayUtil;
import com.iot08.api.utils.wxpay.XMLUtil;
import com.iot08.api.vo.request.*;
import com.iot08.apple.pay.model.ResponseBodyV2;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Map;
import java.util.SortedMap;

/**
 * @version 1.0
 * @Description:
 * @author: Rock
 * @time: 2021/2/27 9:05
 */
@Slf4j
@RestController
@RequestMapping("getway")
public class PayController {

    @Resource
    private PayService payService;
    @Resource
    private WxPayUtil wxPayUtil;
    @Resource
    private HttpServletRequest httpServletRequest;

    /**
     * 支付统一下单
     *
     * @param imei
     * @param vo
     * @time: 2021/2/2 15:54
     * @author: Rock
     * @version 1.0
     */
  /*  @GetMapping("accounts/{imei}/payment")
    public ResponseMap getPayment(@PathVariable("imei") String imei,
                                  @Validated GetPaymentReqVO vo, HttpServletRequest request) throws Exception {
        return payService.getPayment(imei, vo, IPUtil.getIpAddr(request));
    }*/


    /**
     * @description 创建支付记录
     * @author cwj
     * @param [vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2024/12/29 18:22
     **/
    @PostMapping("accounts/payment")
    @CheckAppSign
    public ResponseMap createPaymentInfo(@Validated @RequestBody CreatePaymentReqVO vo) throws Exception {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return payService.createPaymentInfo(vo.getBodyForm(), IPUtil.getIpAddr(request));
    }


    /**
     * @description 创建金币的支付订单
     * @author cwj
     * @param [vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/3/6 10:21
     **/
    @PostMapping("accounts/goldCoinPayment")
    @CheckAppSign
    public ResponseMap createGoldCoinPaymentInfo(@Validated @RequestBody CreateGoldCoinPaymentReqVO vo) throws Exception {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return payService.createGoldCoinPaymentInfo(vo.getBodyForm(), IPUtil.getIpAddr(request));
    }


    /**
     * @description 查询支付状态（微信、支付宝）
     * @author cwj
     * @param [vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/1/4 17:57
     **/
    @PostMapping("accounts/queryPaymentStatus")
    @CheckAppSign
    public ResponseMap queryPaymentOrderStatus(@Validated @RequestBody QueryPaymentStatusReqVo vo){
        return payService.queryPaymentOrderStatus(vo.getBodyForm());
    }
    
    /**
     * @description 查询ApplePay
     * @author cwj
     * @param [vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/1/15 18:25
     **/
    @PostMapping("accounts/queryApplePayTransactionInfo")
    @CheckAppSign
    public ResponseMap queryApplePayTransactionInfo(@Validated @RequestBody ApplePayQueryReqVo vo){
        return payService.queryApplePayTransactionInfo(vo.getBodyForm());
    }

    /**
     * @description 查询苹果支付的历史记录
     * @author cwj
     * @param [vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/2/24 10:06
     **/
    @PostMapping("accounts/queryApplePayHistoryTransactionInfo")
    //@CheckAppSign
    public ResponseMap queryApplePayHistoryTransactionInfo(@Validated @RequestBody ApplePayQueryHistoryReqVo vo){
        return payService.queryApplePayHistoryTransactionInfo(vo.getBodyForm());
    }

    /************************* 支付宝支付回调  *****************************/
    /**
     * 支付宝支付异步回调
     *
     * @param request
     * @time: 2021/2/27 17:27
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("accounts/alipay_payment")
    public String alipayPaymentCallBack(HttpServletRequest request) throws Exception {
        Map<String, String> params = ParamHandle.getRequestParams(request);
        log.info("支付宝异步回调 params= {}", params);
        return payService.alipayPaymentCallBack(params);
    }


    /**
     * 微信支付回调
     *
     * @param request
     * @time: 2021/2/27 18:25
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("accounts/wx_payment")
    public String wxPaymentCallBack(HttpServletRequest request,HttpServletResponse response) throws Exception {
        String serialNo = request.getHeader("Wechatpay-Serial");
        String signature = request.getHeader("Wechatpay-Signature");
        String timestamp = request.getHeader("Wechatpay-Timestamp");
        String nonceStr = request.getHeader("Wechatpay-Nonce");
        //获取请求body
        String requstBody = getRequestBody(request);
        // 打印请求体内容
        log.info("Received body: " + requstBody);
        return payService.wechatPaymentCallBack(serialNo,signature,timestamp,nonceStr,requstBody,response);
    }


    /**
     * @description 微信退款回调通知
     * @author cwj
     * @param [request, response]
     * @return java.lang.String
     * @date @time 2025/2/8 14:55
     **/
    @PostMapping("accounts/wx_refund")
    public String wxRefundCallBack(HttpServletRequest request,HttpServletResponse response) throws Exception {
        String serialNo = request.getHeader("Wechatpay-Serial");
        String signature = request.getHeader("Wechatpay-Signature");
        String timestamp = request.getHeader("Wechatpay-Timestamp");
        String nonceStr = request.getHeader("Wechatpay-Nonce");
        //获取请求body
        String requstBody = getRequestBody(request);
        // 打印请求体内容
        log.info("Received body: " + requstBody);
        return payService.wechatRefundCallBack(serialNo,signature,timestamp,nonceStr,requstBody,response);
    }

    /**
     * @description apple
     * @author cwj
     * @param [request]
     * @return java.lang.String
     * @date @time 2025/1/11 9:50
     **/
    @PostMapping("accounts/apple_payment")
    public ResponseEntity<String> applePaymentCallBack(@RequestBody ResponseBodyV2 responseBodyV2) throws Exception {
        log.info("收到回调通知内容：{}",responseBodyV2.toString());
        return payService.applePaymentCallBack(responseBodyV2);
    }


    /**
     * @description 获取请求体
     * @author cwj
     * @param [request]
     * @return java.lang.String
     * @date @time 2025/1/4 9:16
     **/
    private String getRequestBody(HttpServletRequest request) throws Exception {
        StringBuilder body = new StringBuilder();
        try (BufferedReader reader = request.getReader()) {
            String line;
            while ((line = reader.readLine()) != null) {
                body.append(line);
            }
        }
        return body.toString();
    }


    /**
     * @param map
     * @time: 2021/3/1 9:43
     * @author: Rock
     * @version 1.0
     */
    private boolean checkAppParam(SortedMap<String, String> map) throws Exception {
        String sign = map.get("sign");
        map.remove("sign");
        String createMD5Sign = wxPayUtil.createMD5Sign(map);
        if (!createMD5Sign.equals(sign)) {
            return false;
        }
        return true;
    }

    /**
     * @param
     * @time: 2021/3/1 9:43
     * @author: Rock
     * @version 1.0
     */
    private SortedMap<String, String> parseParam() throws Exception {
        InputStream inStream = httpServletRequest.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        outSteam.close();
        inStream.close();
        String result = new String(outSteam.toByteArray(), "utf-8");
        //提取微信应答参数
        return XMLUtil.xmlToMap(result);
    }

}
